package com.zdxf.client.controller;

import com.alibaba.fastjson.JSONObject;
import com.zdxf.client.domain.SystemInfoDO;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.hardware.NetworkIF;
import oshi.util.FormatUtil;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.Formatter;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.concurrent.TimeUnit;

public class System2 {

    static void printlnCpuInfo(SystemInfoDO res) throws InterruptedException {
        //System.out.println("----------------cpu信息----------------");
        SystemInfo systemInfo = new SystemInfo();
        CentralProcessor processor = systemInfo.getHardware().getProcessor();
        long[] prevTicks = processor.getSystemCpuLoadTicks();
        // 睡眠1s
        TimeUnit.SECONDS.sleep(1);
        long[] ticks = processor.getSystemCpuLoadTicks();
        long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
        long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
        long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
        long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
        long cSys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
        long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
        long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
        long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
        long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
        int cpuCount = processor.getLogicalProcessorCount();
        double systemCpuLoad = cSys * 1.0 / totalCpu;
        double userCpuLoad = user * 1.0 / totalCpu;
        double iowaitCpuLoad = iowait * 1.0 / totalCpu;
        double idleCpuLoad = 1.0 - idle * 1.0 / totalCpu;
        res.setCpuCount(cpuCount);
        res.setSystemCpuLoad(systemCpuLoad);
        res.setUserCpuLoad(userCpuLoad);
        res.setIowaitCpuLoad(iowaitCpuLoad);
        res.setIdleCpuLoad(idleCpuLoad);
        res.setSystemCpuLoadStr(new DecimalFormat("#.##%").format(systemCpuLoad));
        res.setUserCpuLoadStr(new DecimalFormat("#.##%").format(userCpuLoad));
        res.setIowaitCpuLoadStr(new DecimalFormat("#.##%").format(iowaitCpuLoad));
        res.setIdleCpuLoadStr(new DecimalFormat("#.##%").format(idleCpuLoad));
//        java.lang.System.out.println("----------------cpu信息----------------");
//        java.lang.System.out.println("cpu核数:" + processor.getLogicalProcessorCount());
//        java.lang.System.out.println("cpu系统使用率:" + new DecimalFormat("#.##%").format(cSys * 1.0 / totalCpu));
//        java.lang.System.out.println("cpu用户使用率:" + new DecimalFormat("#.##%").format(user * 1.0 / totalCpu));
//        java.lang.System.out.println("cpu当前等待率:" + new DecimalFormat("#.##%").format(iowait * 1.0 / totalCpu));
//        java.lang.System.out.println("cpu当前使用率:" + new DecimalFormat("#.##%").format(1.0 - (idle * 1.0 / totalCpu)));
    }

    public static void NetInfo(SystemInfoDO res) throws InterruptedException {
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        List<NetworkIF> networkIFs = hal.getNetworkIFs();
//        for (NetworkIF net : networkIFs) {
//            java.lang.System.out.println("----------------网络信息----------------");
//            java.lang.System.out.format(" 网络设备名: %s (%s)%n", net.getName(), net.getDisplayName());
//            java.lang.System.out.format("   MAC地址: %s %n", net.getMacaddr());
//            java.lang.System.out.format("   xxxxxxxxxx: %s %n", net.getSpeed());
//            java.lang.System.out.format("   MTU: %s, Speed: %s %n", net.getMTU(), FormatUtil.formatValue(net.getSpeed(), "bps"));
//            java.lang.System.out.format("   IPv4: %s %n", Arrays.toString(net.getIPv4addr()));
//            java.lang.System.out.format("   IPv6: %s %n", Arrays.toString(net.getIPv6addr()));
//            boolean hasData = net.getBytesRecv() > 0 || net.getBytesSent() > 0 || net.getPacketsRecv() > 0
//                    || net.getPacketsSent() > 0;
//            java.lang.System.out.format("   流量：已接收 %s/%s%s; 已传输 %s/%s%s %n",
//                    hasData ? net.getPacketsRecv() + " 包" : "?",
//                    hasData ? FormatUtil.formatBytes(net.getBytesRecv()) + "-" + net.getBytesRecv() : "?",
//                    hasData ? " (" + net.getInErrors() + " err)" : "",
//                    hasData ? net.getPacketsSent() + " 包" : "?",
//                    hasData ? FormatUtil.formatBytes(net.getBytesSent()) + "-" + net.getBytesSent() : "?",
//                    hasData ? " (" + net.getOutErrors() + " err)" : "");
//        }
        long Recv1 = 0;
        long Sent1 = 0;
        long Recv2 = 0;
        long Sent2 = 0;
        for (NetworkIF net : networkIFs) {
            Recv1 += net.getBytesRecv() > 0 ? net.getBytesRecv() : 0;
            Sent1 += net.getBytesSent() > 0 ? net.getBytesSent() : 0;
        }
        TimeUnit.SECONDS.sleep(1);
        si = new SystemInfo();
        hal = si.getHardware();
        networkIFs = hal.getNetworkIFs();
        for (NetworkIF net : networkIFs) {
            Recv2 += net.getBytesRecv() > 0 ? net.getBytesRecv() : 0;
            Sent2 += net.getBytesSent() > 0 ? net.getBytesSent() : 0;
        }

        res.setNetRecv(Recv2 - Recv1);
        res.setNetSent(Sent2 - Sent1);
        res.setNetSentStr(formatNumber((Sent2 - Sent1)
                / (float) (1024 * 1024)));
        res.setNetRecvStr(formatNumber((Recv2 - Recv1)
                / (float) (1024 * 1024)));
    }

    public static void MemInfo(SystemInfoDO res) {
        SystemInfo systemInfo = new SystemInfo();
        GlobalMemory memory = systemInfo.getHardware().getMemory();
        //总内存
        long totalByte = memory.getTotal();
        //剩余
        long availableByte = memory.getAvailable();
        res.setMemoryTotal(totalByte);//操作系统总物理内存
        res.setMemoryFree(availableByte);//操作系统物理剩余内存
        res.setMemoryUse(totalByte - availableByte);//操作系统物理内存使用
        res.setMemoryTotalStr(FormatUtil.formatBytes(totalByte));
        res.setMemoryFreeStr(FormatUtil.formatBytes(availableByte));
        res.setMemoryUseStr(FormatUtil.formatBytes(totalByte - availableByte));
        //        java.lang.System.out.println("----------------主机内存信息----------------");
//        java.lang.System.out.println("总内存 = " + FormatUtil.formatBytes(totalByte));
//        java.lang.System.out.println("使用" + FormatUtil.formatBytes(totalByte - availableByte));
//        java.lang.System.out.println("剩余内存 = " + FormatUtil.formatBytes(availableByte));
//        java.lang.System.out.println("使用率：" + new DecimalFormat("#.##%").format((totalByte - availableByte) * 1.0 / totalByte));
    }

    public static void DiskInfo(SystemInfoDO res) {
        File[] disks = File.listRoots();
        long disksTotal = 0;
        long disksUse = 0;
        long disksFree = 0;
        for (File file : disks) {
            disksTotal += file.getTotalSpace();
            disksUse += file.getTotalSpace() - file.getUsableSpace();
            disksFree += file.getFreeSpace();
            //        java.lang.System.out.println("---------------主机硬盘信息----------------");
//            java.lang.System.out.print(file.getPath() + "    ");
//            java.lang.System.out.print("空闲未使用 = " + FormatUtil.formatBytes(file.getFreeSpace()) + "    ");// 空闲空间
//            java.lang.System.out.print("已经使用 = " + FormatUtil.formatBytes(file.getTotalSpace() - file.getUsableSpace()) + "    ");// 已经使用
//            java.lang.System.out.print("总容量 = " + FormatUtil.formatBytes(file.getTotalSpace()) + "    ");// 总空间
//            java.lang.System.out.println();
        }
        res.setDisksTotal(disksTotal);
        res.setDisksUse(disksUse);
        res.setDisksFree(disksFree);
        res.setDisksTotalStr(FormatUtil.formatBytes(disksTotal));
        res.setDisksFreeStr(FormatUtil.formatBytes(disksFree));
        res.setDisksUseStr(FormatUtil.formatBytes(disksUse));
    }

    public static void setSysInfo(SystemInfoDO res) {
        Properties props = java.lang.System.getProperties();
        //系统名称
        String osName = props.getProperty("os.name");
        //架构名称
        String osArch = props.getProperty("os.arch");
        res.setOsName(osName);//操作系统的版本
        res.setOsArch(osArch);//系统架构
        //        java.lang.System.out.println("----------------操作系统信息----------------");
//        java.lang.System.out.println("操作系统名 = " + osName);
//        java.lang.System.out.println("系统架构 = " + osArch);
    }

    public static String isWindowsOrLinux(SystemInfoDO res) {
        String osName = res.getOsName();
        String sysName = "";
        if (osName.toLowerCase().startsWith("windows")) {
            sysName = "windows";
        } else if (osName.toLowerCase().startsWith("linux")) {
            sysName = "linux";
        }
        return sysName;
    }


    public static String getNetworkThroughput(SystemInfoDO res) throws IOException {
        String throughput = "";
        if (isWindowsOrLinux(res).equals("windows")) { // 判断操作系统类型是否为：windows
            getNetworkThroughputForWindows(); // 查询windows系统的磁盘读写速率
        } else {
            getNetworkThroughputForLinux(); // 查询linux系统的磁盘读写速率
        }
        return throughput;
    }

    public static void getNetworkThroughputForWindows() throws IOException {
        Process pro1 = null;
        Process pro2 = null;
        Runtime r = Runtime.getRuntime();
        BufferedReader input = null;
        String rxPercent = "";
        String txPercent = "";
        try {
            String command = "netstat -e";
            pro1 = r.exec(command);
            input = new BufferedReader(new InputStreamReader(pro1.getInputStream()));
            String result1[] = readInLine(input, "windows");
            Thread.sleep(1000);
            pro2 = r.exec(command);
            input = new BufferedReader(new InputStreamReader(pro2.getInputStream()));
            String result2[] = readInLine(input, "windows");
            rxPercent = formatNumber((Long.parseLong(result2[0]) - Long.parseLong(result1[0]))
                    / (float) (1024 * 1024 * (1000 / 1000))); // 上行速率(MB/s)
            txPercent = formatNumber((Long.parseLong(result2[1]) - Long.parseLong(result1[1]))
                    / (float) (1024 * 1024 * (1000 / 1000))); // 下行速率(MB/s)
            input.close();
            pro1.destroy();
            pro2.destroy();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        java.lang.System.out.println(rxPercent);
        java.lang.System.out.println(txPercent);
        //return JSON.toJSONStringWithDateFormat(jsonObject, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteMapNullValue);
    }

    public static void getNetworkThroughputForLinux() throws IOException {
        Process pro1 = null;
        Process pro2 = null;
        Runtime r = Runtime.getRuntime();
        BufferedReader input = null;
        String rxPercent = "";
        String txPercent = "";
        JSONObject jsonObject = new JSONObject();
        try {
            String command = "nload";
            pro1 = r.exec(command);
            input = new BufferedReader(new InputStreamReader(pro1.getInputStream()));
            java.lang.System.out.println("3333");
            String result1[] = readInLine(input, "linux");
            Thread.sleep(1000);
            pro2 = r.exec(command);
            input = new BufferedReader(new InputStreamReader(pro2.getInputStream()));
            String result2[] = readInLine(input, "linux");
            java.lang.System.out.println("222222");

            rxPercent = formatNumber((Long.parseLong(result2[0]) - Long.parseLong(result1[0]))
                    / (float) (1024 * 1024 * (1000 / 1000))); // 下行速率(MB/s)
            txPercent = formatNumber((Long.parseLong(result2[1]) - Long.parseLong(result1[1]))
                    / (float) (1024 * 1024 * (1000 / 1000))); // 上行速率(MB/s)
            input.close();
            pro1.destroy();
            pro2.destroy();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        jsonObject.put("rxPercent", rxPercent); // 下行速率
        jsonObject.put("txPercent", txPercent); // 上行速率
        java.lang.System.out.println(rxPercent);
        java.lang.System.out.println(txPercent);
        /// return JSON.toJSONStringWithDateFormat(jsonObject, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteMapNullValue);
    }

    public static String[] readInLine(BufferedReader input, String osType) throws IOException {
        String rxResult = "";
        String txResult = "";
        StringTokenizer tokenStat = null;
        try {
            if (osType.equals("linux")) { // 获取linux环境下的网口上下行速率
                String result[] = input.readLine().split(" ");
                int j = 0, k = 0;
                for (int i = 0; i < result.length; i++) {
                    java.lang.System.out.println(result[i]);

//                    if (result[i].indexOf("RX") != -1) {
//                        j++;
//                        if (j == 2) {
//                            rxResult = result[i + 1].split(":")[1];
//                        }
//                    }
//                    if (result[i].indexOf("TX") != -1) {
//                        k++;
//                        if (k == 2) {
//                            txResult = result[i + 1].split(":")[1];
//                            break;
//                        }
//                    }
                }

            } else { // 获取windows环境下的网口上下行速率
                input.readLine();
                input.readLine();
                input.readLine();
                input.readLine();
                tokenStat = new StringTokenizer(input.readLine());
                tokenStat.nextToken();
                rxResult = tokenStat.nextToken();
                txResult = tokenStat.nextToken();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        String arr[] = {rxResult, txResult};
        return arr;
    }

    private static String formatNumber(Object obj) {
        String result = "";
        if (obj.getClass().getSimpleName().equals("Float")) {
            result = new Formatter().format("%.2f", (float) obj).toString();
        } else if (obj.getClass().getSimpleName().equals("Double")) {
            result = new Formatter().format("%.2f", (double) obj).toString();
        }
        return result;
    }

}
